#include "dw_net.hpp"
#include "test_common.hpp"

#include <iostream>

uint32_t dw::net::Scramble(uint32_t in)
{
    return in / 2;
}

class CustomServer : public dw::net::server_interface<MsgTypes>
{
public:
    CustomServer(uint16_t nPort) : dw::net::server_interface<MsgTypes>(nPort)
    {
    }

public:
    virtual void OnClientValidate(std::shared_ptr<dw::net::connection<MsgTypes>> client)
    {
        std::cout << "[SERVER] Client [" << client->GetID() << "] Validated!" << std::endl;
        dw::net::message<MsgTypes> msg(MsgTypes::AssignID);
        uint32_t uid = htonl(client->GetID());
        msg << uid;
        client->Send(msg);
    }

protected:
    virtual bool OnClientConnect(std::shared_ptr<dw::net::connection<MsgTypes>> client)
    {
        // dw::net::message<MsgTypes> msg(MsgTypes::ServerAccept);
        // client->Send(msg);
        return true;
    }

    virtual void OnClientDisconnect(std::shared_ptr<dw::net::connection<MsgTypes>> client)
    {
        std::cout << "[SERVER] Removing client <" << client->GetID() << ">" << std::endl;
    }

    virtual void OnMessage(std::shared_ptr<dw::net::connection<MsgTypes>> client, dw::net::message<MsgTypes> &msg)
    {
        switch (msg.type())
        {
        case MsgTypes::ServerPing:
        {
            std::cout << "[" << client->GetID() << "]: Server Ping" << std::endl;
            client->Send(msg);
        }
        break;

        case MsgTypes::MessageAll:
        {
            std::cout << "[" << client->GetID() << "]: Message All" << std::endl;
            dw::net::message<MsgTypes> msg(MsgTypes::ServerMessage);
            msg << client->GetID();
            MessageAllClients(msg, client);
        }
        }
    }
};

int main()
{
    CustomServer server(60000);
    server.Start();

    while (1)
    {
        server.Update(-1, true);
    }

    return 0;
}